package com.sale.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.redis.utils.RedisUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.system.domain.*;
import com.sale.system.domain.dto.*;
import com.sale.system.domain.vo.SysAccountsUpdateVo;
import com.sale.system.domain.vo.SysAccountsVo;
import com.sale.system.domain.vo.SysFunctionalParameterVo;
import com.sale.system.domain.vo.SysInventoryAccountingVo;
import com.sale.system.mapper.*;
import com.sale.system.service.ISysAccountsService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @Description 账套管理
 * @Param SysAccounts
 * @Date 23-07-07
 * @Author hl
 **/
@RequiredArgsConstructor
@Service
public class SysAccountsServiceImpl implements ISysAccountsService {

    /**
     * 账套管理Mapper
     */
    private final SysAccountsMapper sysAccountsMapper;


    /**
     * 功能参数Mapper
     */
    private final SysFunctionalParameterMapper sysFunctionalParameterMapper;

    /**
     * 存货核算Mapper
     */
    private final SysInventoryAccountingMapper sysInventoryAccountingMapper;

    /**
     * 参数说明Mapper
     */
    private final SysParameterDescriptionMapper sysParameterDescriptionMapper;

    /**
     * 存货核算明细
     */
    private final SysAccountingDetailMapper sysAccountingDetailMapper;

    /**
     * 用户
     */
    private final SysUserMapper sysUserMapper;

    /**
     * 角色
     */
    private final SysRoleMapper sysRoleMapper;

    /**
     * 账套管理查询
     *
     * @param
     * @return 账套管理集合
     */
    @Override
    public List<SysAccountsDto> selectAccountsList() {
        Long userId = LoginHelper.getUserId();
        return sysAccountsMapper.selectAccountsList(userId);
    }

    /**
     * 账套信息系统参数集合
     *
     * @param
     * @return 账套管理集合
     */
    @Override
    public SysAccountsDetailsDto selectAccountsDetailsList(Long accountsId) {

        // 根据id查询账套信息
        SysAccountsDetailsDto sysAccountsDetailsDto = sysAccountsMapper.selectAccountsDetailsList(accountsId);

        // 功能参数
        List<SysFunctionalParameterDto> sysFunctionalParameterDtos = sysFunctionalParameterMapper.selectFunctionalParameterList(accountsId);

        // 存货核算
        SysInventoryAccountingDto sysInventoryAccountingDto = sysInventoryAccountingMapper.selectInventoryAccountingList(accountsId);
        if(sysInventoryAccountingDto != null){
            // 存货核算明细
            List<SysAccountingDetailDto> sysAccountingDetailDtos = sysAccountingDetailMapper.selectAccountingDetailList(sysInventoryAccountingDto.getInventoryAccountingId());
            sysInventoryAccountingDto.setAccountingDtoList(sysAccountingDetailDtos);
        }

        sysAccountsDetailsDto.setSysFunctionalParameterList(sysFunctionalParameterDtos);
        sysAccountsDetailsDto.setSysInventoryAccountingDto(sysInventoryAccountingDto);

        return sysAccountsDetailsDto;
    }


    /**
     * 新增账套管理
     *
     * @param sysAccountsVo
     * @return int
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertAccounts(SysAccountsVo sysAccountsVo) {
        // 查询公司名称是否已存在
        Long userId = LoginHelper.getUserId();
        SysAccounts sysAccountsName = sysAccountsMapper.selectOne(new QueryWrapper<SysAccounts>().lambda().eq(SysAccounts::getAccountsName, sysAccountsVo.getAccountsName()).eq(SysAccounts::getTenantId, userId));
        if (sysAccountsName != null) {
            throw new GlobalException("该公司名称已存在");
        }

        SysAccounts sysAccounts = new SysAccounts();
        BeanUtil.copyProperties(sysAccountsVo, sysAccounts);
        sysAccounts.setAccountsTime(new Date());
        sysAccounts.setAccountsStatus(1);
        sysAccounts.setTenantId(userId);
        // 新增账套信息
        int insert = sysAccountsMapper.insert(sysAccounts);
        if (insert > 0) {
            boolean insertList = false;
            // 查询基础参数说明表
            List<SysParameterDescription> list = sysParameterDescriptionMapper.selectList(new QueryWrapper<SysParameterDescription>().lambda().eq(SysParameterDescription::getType, 1));
            for (SysParameterDescription sysParameterDescription : list) {

                // 添加功能参数信息
                SysFunctionalParameter sysFunctionalParameter = new SysFunctionalParameter();
                // 功能参数操作状态（1、开启, 2、关闭）
                sysFunctionalParameter.setOperatingState(1);
                // 账套id
                sysFunctionalParameter.setAccountsId(sysAccounts.getAccountsId());
                // 参数说明id
                sysFunctionalParameter.setDescriptionId(sysParameterDescription.getDescriptionId());
                // 新增功能参数
                int insert1 = sysFunctionalParameterMapper.insert(sysFunctionalParameter);

                // 判断是否新增成功
                if (insert1 > 0) {
                    insertList = true;
                }
            }
            // 如果功能参数新增成功
            if (insertList) {
                SysInventoryAccounting sysInventoryAccounting = new SysInventoryAccounting();
                sysInventoryAccounting.setCostAccountingMethod(1);
                sysInventoryAccounting.setCostAccountingWay(1);
                sysInventoryAccounting.setAccountsId(sysAccounts.getAccountsId());
                int insert2 = sysInventoryAccountingMapper.insert(sysInventoryAccounting);
                if (insert2 > 0) {
                    // 新增存货核算明细
                    List<SysParameterDescription> list1 = sysParameterDescriptionMapper.selectList(new QueryWrapper<SysParameterDescription>().lambda().eq(SysParameterDescription::getType, 2));
                    for (SysParameterDescription sysParameterDescription : list1) {
                        SysAccountingDetail sysAccountingDetail = new SysAccountingDetail();
                        // 参数说明id
                        sysAccountingDetail.setDescriptionId(sysParameterDescription.getDescriptionId());
                        // 存货核算id
                        sysAccountingDetail.setInventoryAccountingId(sysInventoryAccounting.getInventoryAccountingId());
                        // 默认已操作
                        sysAccountingDetail.setAccountingOperate(1);
                        sysAccountingDetailMapper.insert(sysAccountingDetail);
                    }
                }
            }
        } else {
            throw new GlobalException("新增账套失败");
        }
        sysAccountsMapper.insertSysAccountsUser(sysAccounts);
        return insert;
    }

    /**
     * 修改账套管理
     *
     * @param sysAccountsUpdateVo
     * @return int
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateAccounts(SysAccountsUpdateVo sysAccountsUpdateVo) {
        SysAccounts sysAccounts = new SysAccounts();
        BeanUtils.copyProperties(sysAccountsUpdateVo, sysAccounts);
        // 修改基础参数
        int update = sysAccountsMapper.updateById(sysAccounts);
//        if (update > 0) {
//            List<SysFunctionalParameter> sysFunctionalParameters = sysFunctionalParameterMapper.selectList(new QueryWrapper<SysFunctionalParameter>().lambda().eq(SysFunctionalParameter::getAccountsId, sysAccounts.getAccountsId()));
//            sysFunctionalParameterMapper.deleteBatchIds(sysFunctionalParameters);
//            // 查询基础参数说明表
//
//            List<SysFunctionalParameterVo> sysFunctionalParameterList = sysAccountsUpdateVo.getSysFunctionalParameterList();
//
//            List<SysFunctionalParameter> functionalParameterList = new ArrayList<>();
//            for (SysFunctionalParameterVo sysFunctionalParameterVo : sysFunctionalParameterList) {
//                SysFunctionalParameter sysFunctionalParameter = new SysFunctionalParameter();
//                // 功能参数操作状态（1、开启, 2、关闭）
//                sysFunctionalParameter.setOperatingState(sysFunctionalParameterVo.getOperatingState());
//                // 账套id
//                sysFunctionalParameter.setAccountsId(sysAccounts.getAccountsId());
//                // 参数说明id
//                sysFunctionalParameter.setDescriptionId(sysFunctionalParameterVo.getDescriptionId());
//                functionalParameterList.add(sysFunctionalParameter);
//            }
//            // 新增功能参数
//            boolean b = sysFunctionalParameterMapper.insertBatch(functionalParameterList);
//
//            if (b) {
//
//                // 查询功能参数和存货核算
//                SysInventoryAccounting sysInventoryAccounting1 = sysInventoryAccountingMapper.selectOne(new QueryWrapper<SysInventoryAccounting>().lambda().eq(SysInventoryAccounting::getAccountsId, sysAccounts.getAccountsId()));
//                List<SysAccountingDetail> sysAccountingDetails = sysAccountingDetailMapper.selectList(new QueryWrapper<SysAccountingDetail>().lambda().eq(SysAccountingDetail::getInventoryAccountingId, sysInventoryAccounting1.getInventoryAccountingId()));
//                sysAccountingDetailMapper.deleteBatchIds(sysAccountingDetails);
//                sysInventoryAccountingMapper.deleteById(sysInventoryAccounting1.getInventoryAccountingId());
//
//                // 添加存货核算
//                SysInventoryAccountingVo sysInventoryAccountingVo = sysAccountsUpdateVo.getSysInventoryAccounting();
//                SysInventoryAccounting sysInventoryAccounting = new SysInventoryAccounting();
//                BeanUtils.copyProperties(sysInventoryAccountingVo, sysInventoryAccounting);
//                sysInventoryAccounting.setAccountsId(sysAccounts.getAccountsId());
//                int insert2 = sysInventoryAccountingMapper.insert(sysInventoryAccounting);
//                if (insert2 > 0) {
//                    // 新增存货核算明细
//                    List<SysAccountingDetail> accountingDetailList = sysInventoryAccountingVo.getAccountingDetailList();
//                    List<SysAccountingDetail> list2 = new ArrayList<>();
//                    for (SysAccountingDetail sysAccountingDetail : accountingDetailList) {
//                        // 参数说明id
//                        sysAccountingDetail.setDescriptionId(sysAccountingDetail.getDescriptionId());
//                        // 存货核算id
//                        sysAccountingDetail.setInventoryAccountingId(sysInventoryAccounting.getInventoryAccountingId());
//                        // 默认已操作
//                        sysAccountingDetail.setAccountingOperate(sysAccountingDetail.getAccountingOperate());
//                        list2.add(sysAccountingDetail);
//                    }
//                    sysAccountingDetailMapper.insertBatch(list2);
//                }
//            }
//        }

        return update;
    }

    /**
     * 修改功能参数
     *
     * @param sysFunctionalParameterVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateSysFunctionalParameter(List<SysFunctionalParameterVo> sysFunctionalParameterVo) {
        boolean up = false;
        for (SysFunctionalParameterVo vo : sysFunctionalParameterVo) {
            // 循环修改多条数据
            int b = sysFunctionalParameterMapper.updateFunctionalParameterId(String.valueOf(vo.getFunctionalId()), vo.getOperatingState());
            if (b > 0) {
                up = true;
            } else {
                throw new GlobalException("修改功能参数失败");
            }
        }
        return up;
    }

    /**
     * 修改库存核算
     *
     * @param sysInventoryAccountingVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateSysInventoryAccounting(SysInventoryAccountingVo sysInventoryAccountingVo) {

        SysInventoryAccounting sysInventoryAccounting = new SysInventoryAccounting();
        BeanUtils.copyProperties(sysInventoryAccountingVo, sysInventoryAccounting);
        // 修改存货核算
        int i = sysInventoryAccountingMapper.updateById(sysInventoryAccounting);
        if (i > 0) {
            List<SysAccountingDetail> accountingDetailList = sysInventoryAccountingVo.getAccountingDetailList();
            // 修改存货核算明细
            sysAccountingDetailMapper.updateBatchById(accountingDetailList);
        } else {
            throw new GlobalException("修改存货核算失败");
        }
        return i;
    }

    /**
     * 删除账套管理
     *
     * @param accountsId
     * @return int
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteAccounts(long accountsId) {
        // 删除账套信息
        int deleteAccount = sysAccountsMapper.deleteById(accountsId);
        // 账套信息删除成功后删除功能参数
        if (deleteAccount > 0) {
            int i = sysFunctionalParameterMapper.deleteFunctionalParameterId(accountsId);
            // 删除功能参数成功后删除存货核算
            if (i > 0) {
                // 获取存货核算id，删除明细
                SysInventoryAccounting sysInventoryAccounting = sysInventoryAccountingMapper.selectOne(new QueryWrapper<SysInventoryAccounting>().lambda().eq(SysInventoryAccounting::getAccountsId, accountsId));
                if (sysInventoryAccounting != null) {
                    sysAccountingDetailMapper.deleteAccountingDetailId(sysInventoryAccounting.getInventoryAccountingId());
                }
                sysInventoryAccountingMapper.deleteInventoryAccountingId(accountsId);
            } else {
                throw new GlobalException("删除账套失败");
            }
        } else {
            throw new GlobalException("删除账套失败");
        }
        return deleteAccount;
    }

    /**
     * 更改租户值(缓存)
     *
     * @param id
     * @return int
     */
    @Override
    public void selectTenant(String id) {
        String userIdStr = LoginHelper.getUserIdStr();
        //更改用户账套默认值
        sysUserMapper.updateAccountsById(userIdStr, id);
        //更改账套默认值
        //sysUserMapper.updateAccountsById(userIdStr,id);
        //将值放入缓存
        RedisUtils.setCacheObject(userIdStr, id);
    }

    /**
     * 登录默认获取该用户下第一个帐套信息(缓存)
     *
     * @param userName,userId
     * @return void
     */
    @Override
    public void selectTenantMerlin(String userName, long userId) {
        String userIdStr = sysAccountsMapper.selectTenantMerlin(userName);
        RedisUtils.setCacheObject(String.valueOf(userId), userIdStr);
    }

    /**
     * 无账套的情况下(新增)
     *
     * @param accountsEmpty
     * @return int
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertAccountsEmpty(AccountsEmpty accountsEmpty) {
        long id = IdWorker.getId();
        accountsEmpty.setAccountsId(id);
        accountsEmpty.setCreateBy(LoginHelper.getUsername());
        int i = sysAccountsMapper.insertAccountsEmpty(accountsEmpty);
        //更新用户的默认账套
        sysUserMapper.updateAccountsById(LoginHelper.getUserIdStr(), String.valueOf(id));
        return i;
    }

    /**
     * 账套下拉
     */
    @Override
    public List<PullDown> accountsDown() {
        Long userId = LoginHelper.getUserId();
        return sysAccountsMapper.accountsDown(userId);
    }


}
